﻿using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using RbacPermissionManage.Application;
using RbacPermissionManage.Application.Admins;
using RbacPermissionManage.Application.Admins.Dto;
using RbacPermissionManage.DoMain;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;

namespace RbacPermissionManage.WebAPI.Controllers
{
    /// <summary>
    /// 管理员控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    //[Authorize]
    public class AdminController : ControllerBase
    {
        //管理员接口
        private readonly IAdminServices adminServices;
        private readonly ICaptcha _captcha;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="adminServices"></param>
        public AdminController(IAdminServices adminServices, ICaptcha captcha)
        {
            this.adminServices = adminServices;
            this._captcha = captcha;
        }

        /// <summary>
        /// 显示测试
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(1);
        }

        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="registerDto">注册DTO</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Register(RegisterDto registerDto)
        {
            var result=await adminServices.Register(registerDto);
            return Ok(result);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginDto"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> LoginAsync(LoginDto loginDto)
        {
            string token = this.CreateTokenString(loginDto.UserName);
            var user = await adminServices.LoginAsync(loginDto);
            return Ok(new {user=user,token=token});
        }

        /// <summary>
        /// 生成 JWT Token（令牌）
        /// </summary>
        /// <returns></returns>
        private string CreateTokenString(string account)
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            //设置jwt的claim
            Claim[] claims = new Claim[] {
                new Claim(ClaimTypes.Name,account),//账号
            };
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: "BeiJingBW",
                audience: "BeiJingBW",
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials,
                claims: claims
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }

        [HttpGet]
        [Route("captcha")]
        public IActionResult Captcha(string id)
        {
            var info = _captcha.Generate(id);
            // 有多处验证码且过期时间不一样，可传第二个参数覆盖默认配置。
            //var info = _captcha.Generate(id,120);
            var stream = new MemoryStream(info.Bytes);
            return File(stream, "image/gif");
        }

        /// <summary>
        /// 演示时使用HttpGet传参方便，这里仅做返回处理
        /// </summary>
        [HttpGet("validate")]
        public bool Validate(string id, string code)
        {
            return _captcha.Validate(id, code);
        }

        /// <summary>
        /// 查询分页显示管理员列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetAdminAsync([FromQuery]AdminSearchDto searchDto, int pageIndex=1, int pageSize=10)
        {
            try
            {
                var list = await adminServices.GetAdminAsync(searchDto, pageIndex, pageSize);
                return Ok(new
                {
                    Code=Code.Success,
                    Data = new
                    {
                        PageData=list.Data.Item2,
                        Count=list.Data.Item1
                    }
                });
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}
